package com.zhongan.doc.swagger;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;

import io.swagger.annotations.ApiOperation;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 类Swagger2Config.java的实现描述：Swagger2配置
 * API访问地址：http://localhost:8080/swagger-ui.html
 * 
 * @author: tongyufu 2017-12-04 14:58:58
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

	@Value("${env}")
	private String env;

	@Bean
	public Docket createUserApi() {
		return createDocket("用户", "com.zhongan.doc.swagger.action.user", apiInfo(), true);
	}

	@Bean
	public Docket createOrderApi() {
		return createDocket("订单", "com.zhongan.doc.swagger.action.order", apiInfo(), false);
	}

	/**
	 * 创建Swagger API
	 * 
	 * @param groupName API组
	 * @param basePackage 接口所属目录
	 * @param needApiOperation 是否只显示标注了@ApiOperation的方法
	 * @return
	 */
	private Docket createDocket(String groupName, String basePackage, ApiInfo apiInfo, boolean needApiOperation) {
		Predicate<RequestHandler> apis;
		if ("prod".equals(env)) {
			apiInfo = new ApiInfoBuilder().build();
			apis = RequestHandlerSelectors.none();
		} else {
			if (needApiOperation) {
				apis = new Predicate<RequestHandler>() {
					@Override
					public boolean apply(RequestHandler input) {
						boolean apply = declaringClass(input).transform(handlerPackage(basePackage)).or(true);
						if (apply) {
							apply = input.isAnnotatedWith(ApiOperation.class);
						}
						return apply;
					}
				};
			} else {
				apis = RequestHandlerSelectors.basePackage(basePackage);
			}
		}

		return new Docket(DocumentationType.SWAGGER_2).useDefaultResponseMessages(false).groupName(groupName)
				.apiInfo(apiInfo).select().apis(apis).paths(PathSelectors.any()).build();
	}

	private ApiInfo apiInfo() {
		ApiInfoBuilder api = new ApiInfoBuilder();
		api.title("航旅接口");
		api.description("使用Swagger生成的航旅接口文档");
		api.termsOfServiceUrl("https://www.zhongan.com/");
		api.contact(new Contact("仝玉甫", "https://www.zhongan.com/", "tongyufu@zhongan.com"));
		api.version("1.0");
		return api.build();
	}

	@SuppressWarnings("deprecation")
	private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
		return Optional.fromNullable(input.declaringClass());
	}

	private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
		return new Function<Class<?>, Boolean>() {
			@Override
			public Boolean apply(Class<?> input) {
				return input.getPackage().getName().startsWith(basePackage);
			}
		};
	}
}
